﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

using System.IO;
using mesoBoard.Data;
using mesoBoard.Data.Repositories;
using System.Drawing.Imaging;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Web.Mvc;

namespace mesoBoard.Services
{
    public class Posts : IPosts
    {
         
        private IRepositoriesWrapper Repositories;

        public Posts(IRepositoriesWrapper repos)
        {
            this.Repositories = repos;
        }

        public void CreatePost(Post thePost, int threadID, HttpFileCollectionBase files)
        {
            thePost.ThreadID = threadID;
            thePost.Date = DateTime.UtcNow;
            thePost.UserID = int.Parse(HttpContext.Current.User.Identity.Name);

            Repositories.Posts.CreatePost(thePost);

            Files filesServices = new Files(this.Repositories);

            filesServices.CreateAttachments(files, thePost.PostID);

            Repositories.Threads.SyncThread(threadID);
            Repositories.Forums.SyncForum(thePost.Thread.ForumID);
            Repositories.Users.SyncUser(thePost.UserID);
        }

        public Post GetPost(int PostID)
        {
            return Repositories.Posts.GetPost(PostID);
        }

        public void UpdatePost(Post thePost, HttpFileCollectionBase files)
        {
            Repositories.Posts.UpdatePost(thePost);

            Files filesServices = new Files(this.Repositories);
            filesServices.CreateAttachments(files, thePost.PostID);

            Repositories.Threads.SyncThread(thePost.ThreadID);
            Repositories.Forums.SyncForum(thePost.Thread.ForumID);
            Repositories.Users.SyncUser(thePost.UserID);
        }

        public IEnumerable<Post> GetPagedPosts(int ThreadID, int PageNumber, int PageSize)
        {
            IEnumerable<Post> posts = Repositories.Posts.GetPosts(ThreadID);
            posts = posts.OrderBy(x => x.Date);
            posts = posts.Skip((PageNumber - 1) * PageSize).Take(PageSize);
            return posts;
        }


        public bool CanEditPost(int postID, int userID)
        {
            if (userID == 0)
                return false;

            User TheUser = Repositories.Users.GetUser(userID);

            Post ThePost = GetPost(postID);

            if (TheUser.IsInRole("Moderator") || TheUser.IsInRole("Admin"))
                return true;

            Thread TheThread = ThePost.Thread;

            if (TheThread.IsLocked)
                return false;
            else if (ThePost.UserID == userID)
                return ((DateTime.UtcNow - ThePost.Date).TotalSeconds < SiteConfig.TimeLimitToEditPost.IntValue());

            return false;
        }

        public bool CanDeletePost(int postID, int userID)
        {
            if (userID == 0)
                return false;

            User TheUser = Repositories.Users.GetUser(userID);

            if (TheUser.IsInRole("Moderator") || TheUser.IsInRole("Admin"))
                return true;

            return false;
        }

        public string ParseBBCodeText(string PostText)
        {
            if (string.IsNullOrEmpty(PostText))
                return string.Empty;

            PostText = HttpContext.Current.Server.HtmlEncode(PostText);

            UrlHelper Url = new UrlHelper(HttpContext.Current.Request.RequestContext);

            IEnumerable<BBCode> BBCodes = Repositories.BBCodes.GetBBCodes();
            string ParsedText = "";
            ParsedText = PostText.Replace(Environment.NewLine, "<br />");

            MatchCollection code = Regex.Matches(ParsedText, @"\[code=\b([^\]]*)\](.*?)\[/code\]", RegexOptions.Singleline);

            foreach (Match codematch in code)
            {
                if (codematch.Success)
                {
                    string matchcode = codematch.Value.Replace("<br />", Environment.NewLine);
                    ParsedText = ParsedText.Replace(codematch.Value, matchcode);
                }
            }

            foreach (BBCode b in BBCodes)
            {
                string Pat = b.Pattern;

                Regex Reg = new Regex(Pat, RegexOptions.Singleline);

                MatchCollection matches = Reg.Matches(ParsedText);

                if (matches.Count > 0)
                {
                    for (int j = 0; j < matches.Count; j++)
                    {
                        Match m = matches[j];
                        string evaled = b.Parse;

                        if (m.Success)
                        {
                            if (!string.IsNullOrEmpty(evaled))
                            {
                                for (int i = 1; i < m.Groups.Count; i++)
                                {
                                    evaled = evaled.Replace("{" + i + "}", m.Groups[i].Value);
                                }
                                ParsedText = ParsedText.Replace(m.Groups[0].Value, evaled);
                            }
                        }
                    }
                }
            }

            string SmileyPat = @":([\w\?\!'-]+):";
            string SmileyFolder = "~/Images/Smilies/";
            Regex SmileyReg = new Regex(SmileyPat, RegexOptions.Compiled);
            MatchCollection smileymatchs = SmileyReg.Matches(ParsedText);

            foreach (Match m in smileymatchs)
            {
                if (m.Success)
                {
                    if (!string.IsNullOrEmpty(Repositories.Smilies.GetSmileyURL(m.Groups[0].Value)))
                    {
                        Smiley thesmiley = Repositories.Smilies.GetSmiley(m.Groups[0].Value);

                        string evaled = thesmiley.ImageURL;
                        if (!string.IsNullOrEmpty(evaled))
                        {
                            TagBuilder imgtag = new TagBuilder("img");
                            imgtag.Attributes.Add("src", Url.Content(SmileyFolder + evaled));
                            imgtag.Attributes.Add("alt", thesmiley.Title);
                            imgtag.Attributes.Add("title", thesmiley.Title);

                            ParsedText = ParsedText.Replace(m.Groups[0].Value, imgtag.ToString());
                        }
                    }
                }
            }

            return ParsedText;
        }

    }
}